#ifndef __CDeviceWin32_hpp__
#define __CDeviceWin32_hpp__

#include "IDevice.hpp"
#include "FileSystem.hpp"
#include <Windows.h>

namespace ge {

//----------------------------------------------------------------------------//
// CDeviceWin32
//----------------------------------------------------------------------------//

class CDeviceWin32 : public IDevice
{
 public:

     // main

     CDeviceWin32( void );

     virtual void Process( int _action );

     static LRESULT CALLBACK _WndProc( HWND _window, UINT _msg, WPARAM _w_param, LPARAM _l_param );

     LRESULT _HandleMsg( UINT _msg, WPARAM _w_param, LPARAM _l_param );

     FileSystemPtr m_filesystem;

     // display

     virtual void SetDisplayMode( uint _id );

     virtual uint GetDisplayMode( void );

     virtual const Display::Info& GetDisplayInfo( void );

     virtual uint GetDefaultDisplayMode( void );

     virtual uint GetCurrentDisplayMode( void );


     void _InitDisplay( void );

     static bool _ReadDisplayMode( int _index, Display::ModeEx& _mode );

     void _ApplyDisplayMode( uint _index ) const;

     static void _RestoreDisplayMode( void );

     Display::Info m_display_info;
     uint m_display_mode;



     // window

     virtual void SetWindowCallbacks( OnWindowActivatingPfn _activate_cb, OnWindowMovePfn _move_cb, OnWindowResizePfn _resize_cb, OnWindowClosePfn _close_cb );

     virtual bool GetShow( void );

     virtual void SetShow( bool _enabled = true );
     
     virtual Window::ShowType GetShowType( void );

     virtual Window::ShowType GetNormalShowType( void );

     virtual void SetShowType( Window::ShowType _type );

     virtual Size2ui GetSize( void );

     virtual Size2ui GetNormalSize( void );

     virtual void ResizeWindow( uint _width, uint _height );

     virtual Point2i GetPos( void );

     virtual Point2i GetNormalPos( void );

     virtual void MoveWindow( int _x, int _y );

     virtual bool GetResizable( void );

     virtual void SetResizable( bool _enabled );

     virtual bool GetFullscreen( void );

     virtual void SetFullscreen( bool _enabled );

     virtual String GetTitle( void );

     virtual void SetTitle( const String& _title );

     virtual bool IsActive( void );

     void _InitWindow( void );

     void _SetWindowPlacement( int _x, int _y, uint _w, uint _h, bool _show, bool _activate, Window::ShowType _current, Window::ShowType _install );
     
     void _SetWindowStyle( bool _topmost, bool _caption, bool _resizable );

     void _StartFullscreen( void );

     void _PauseFullscreen( void );

     void _StopFullscreen( void );

     
     void _OnCloseWindow( void );

     void _OnResize( uint _w, uint _h, Window::ShowType _st );

     void _OnMove( int _x, int _y, Window::ShowType _st );

     void _OnActivate( bool _activate );

     void _OnFocus( bool _focus );

     void _OnShow( bool _show );


     OnWindowActivatingPfn m_window_activate_cb;
     OnWindowMovePfn m_window_move_cb;
     OnWindowResizePfn m_window_resize_cb;
     OnWindowClosePfn m_window_close_cb;
     
     uint16 m_atom;
     HWND m_window;
     HDC m_dc;
     bool m_show_window;
     Window::ShowType m_current_show_type;
     Window::ShowType m_normal_show_type;
     bool m_resizable;
     Size2ui m_current_size;
     Size2ui m_normal_size;
     Point2i m_current_pos;
     Point2i m_normal_pos;
     bool m_active;
     bool m_fullscreen;
     String m_title;

     // keyboard

     OnKeyboardFocusPfn m_keyboard_focus_cb;
     OnKeyboardKeyPfn m_keyboard_key_cb;
     bool m_keyboard_focus;
     uint32 m_ctrlkeys;
     uint m_keys[Keyboard::Key_Max];
     Keyboard::Key m_last_key;

     virtual void SetKeyboardCallbacks( OnKeyboardFocusPfn _focus_cb, OnKeyboardKeyPfn _key_cb );

     virtual const uint* GetKeyboardState( void );

     virtual uint32 GetCtrlKeysState( void );

     virtual void ClearKeyboardEventQueue( void );

     void _InitKeyboard( void );

     void _UpdateKeyboardState( void );

     void _UpdateCtrlKeys( uint8* _keys );

     static Keyboard::Key _TranslateKey( int _key, int _code );

     void _OnKeyboardFocus( bool _focus );

     void _OnKeyboardEvent( Keyboard::Key _key, bool _press );

     // mouse

     virtual void SetMouseCallbacks( OnMouseFocusPfn _focus_cb, OnMouseMovePfn _move_cb, OnMouseButtonPfn _button_cb, OnMouseWheelPfn _wheel_cb ); 

     virtual uint32 GetMouseState( void );

     virtual bool GetCursorClip( void );

     virtual void SetCursorClip( bool _enabled );

     virtual Point2i GetCursorPos( void );

     virtual void SetCursorPos( int _x, int _y );

     virtual bool GetShowCursor( void );

     virtual void SetShowCursor( bool _enabled );

     virtual void ClearMouseEventQueue( void );


     void _InitMouse( void );

     void _OnMouseFocus( bool _focus );

     void _OnMouseMove( int _x, int _y );

     void _OnMouseButtonEvent( int _x, int _y, Mouse::Button _button, bool _press );

     void _OnMouseWheelEvent( int _wheel );

     void _UpdateMouse( void );

     struct ClickParams
     {
          Point2i diff;
          uint time;
     };

     struct ClickInfo
     {
          Point2i pos;
          uint time;
          uint button;
          uint count;
     };

     OnMouseFocusPfn m_mouse_focus_cb;
     OnMouseMovePfn m_mouse_move_cb;
     OnMouseButtonPfn m_mouse_button_cb;
     OnMouseWheelPfn m_mouse_wheel_cb;
     ClickParams m_click_params; 
     ClickInfo m_click_info;
     Point2i m_abs_cursor_pos;
     Point2i m_cursor_pos;
     bool m_clip_cursor;
     uint m_buttons;
     bool m_show_cursor;
     bool m_mouse_focus;

 protected:

     virtual ~CDeviceWin32( void );

     // main

     // display

     // window

     // keyboard

     // mouse

};

} // namespace ge

#endif//__CDeviceWin32_hpp__
